﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Data.Entities;
using Microsoft.AspNet.Identity;
using Microsoft.Practices.ObjectBuilder2;
using Microsoft.Practices.Unity;
using Repository.Interface;
using Service.Interface;

namespace Service
{
    /// <summary>
    /// 用户服务类
    /// </summary>
    public class SysUserService : ISysUserService
    {
        #region Repository
        [Dependency]
        protected ISysUserRepository SysUserRepository { get; set; }
        [Dependency]
        protected ISysUserLoginInfoRepository SysUserLoginInfoRepository { get; set; }
        #endregion

        #region 获取所有用户
        /// <summary>
        /// 获取所有用户
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        public async Task<IList<SysUser>> FindAsync(Expression<Func<SysUser, bool>> func)
        {
            return await SysUserRepository.FindAsync(func);
        }
        #endregion

        #region 根据条件，获取第一个用户
        /// <summary>
        /// 根据条件，获取第一个用户
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        public async Task<SysUser> FirstAsync(Expression<Func<SysUser, bool>> func)
        {
            return await SysUserRepository.FirstAsync(func);
        }
        #endregion

        #region 通过编号获取用户
        /// <summary>
        /// 通过编号获取用户
        /// </summary>
        /// <param name="code">用户编号</param>
        /// <returns></returns>
        public async Task<SysUser> FindUserByCodeAsync(string code)
        {
            return await SysUserRepository.FirstAsync(c => c.Code.Contains(code));
        }
        #endregion

        #region 删除用户
        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id">用户主键</param>
        public async Task DeleteAsync(Guid id)
        {
            await SysUserRepository.DeleteAsync(id);
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="user">用户</param>
        /// <returns></returns>
        public async Task DeleteAsync(SysUser user)
        {
            var u = await SysUserRepository.FindAsync(user.Id);
            if (u == null) return;
            await SysUserRepository.DeleteAsync(u.Id);
        }

        /// <summary>
        /// 批量删除用户
        /// </summary>
        /// <param name="ids">用户主键集合</param>
        /// <returns></returns>
        public async Task DeleteAsync(IList<Guid> ids)
        {
            await SysUserRepository.DeleteAsync(ids);
        }
        #endregion

        #region 添加登录信息
        /// <summary>
        /// 添加登录信息
        /// </summary>
        /// <param name="user"></param>
        /// <param name="login"></param>
        /// <returns></returns>
        public async Task AddLoginAsync(SysUser user, UserLoginInfo login)
        {
            var u = await SysUserRepository.FindAsync(user.Id);
            if (u == null) return;
            var info = new SysUserLoginInfo()
            {
                UserId = u.Id,
                LoginProvider = login.LoginProvider,
                ProviderKey = login.ProviderKey
            };
            await SysUserLoginInfoRepository.CreateAsync(info);
        }
        #endregion

        #region 新增用户
        /// <summary>
        /// 新增用户
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task CreateAsync(SysUser user)
        {
            await SysUserRepository.CreateAsync(user);
        }
        #endregion

        #region 通过登录信息获取用户
        /// <summary>
        /// 通过登录信息获取用户
        /// </summary>
        /// <param name="login"></param>
        /// <returns></returns>
        public async Task<SysUser> FindAsync(UserLoginInfo login)
        {
            var info = await SysUserLoginInfoRepository.FirstAsync(c => c.LoginProvider == login.LoginProvider && c.ProviderKey == login.ProviderKey);
            if (info == null) return null;
            return await SysUserRepository.FindAsync(info.UserId);
        }
        #endregion

        #region 根据邮箱获取用户
        /// <summary>
        /// 根据邮箱获取用户
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        public async Task<SysUser> FindByEmailAsync(string email)
        {
            return await SysUserRepository.FirstAsync(c => c.Email == email);
        }
        #endregion

        #region 根据主键获取用户
        /// <summary>
        /// 根据主键获取用户
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<SysUser> FindByIdAsync(Guid userId)
        {
            return await SysUserRepository.FindAsync(userId);
        }
        #endregion

        #region 根据用户名获取用户
        /// <summary>
        /// 根据用户名获取用户
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public async Task<SysUser> FindByNameAsync(string userName)
        {
            return await SysUserRepository.FirstAsync(c => c.UserName == userName);
        }
        #endregion

        #region 获取邮箱
        /// <summary>
        /// 获取邮箱
        /// </summary>
        /// <param name="user">用户</param>
        /// <returns></returns>
        public async Task<string> GetEmailAsync(SysUser user)
        {
            var u = await SysUserRepository.FindAsync(user.Id);
            if (u == null) return "";
            return u.Email;
        }
        #endregion

        #region 锁定用户账号
        /// <summary>
        /// 锁定用户账号
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task<bool> GetLockoutEnabledAsync(SysUser user)
        {
            return await Task.FromResult(false);
        }
        #endregion

        #region 获取账号解除锁定时间点
        /// <summary>
        /// 获取账号解除锁定时间点
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task<DateTimeOffset> GetLockoutEndDateAsync(SysUser user)
        {
            return await Task.FromResult(new DateTimeOffset(DateTime.Now));
        }
        #endregion

        #region 获取登录信息
        /// <summary>
        /// 获取登录信息
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task<IList<UserLoginInfo>> GetLoginsAsync(SysUser user)
        {
            var Info = await SysUserLoginInfoRepository.FindAsync(c => c.UserId == user.Id);
            if (Info == null) return null;
            IList<UserLoginInfo> loginInfos = new List<UserLoginInfo>();
            Info.ForEach(c =>
            {
                loginInfos.Add(new UserLoginInfo(c.LoginProvider, c.ProviderKey));
            });
            return loginInfos;
        }
        #endregion

        #region 获取哈希密码
        /// <summary>
        /// 获取哈希密码
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task<string> GetPasswordHashAsync(SysUser user)
        {
            var u = await SysUserRepository.FindAsync(user.Id);
            if (u == null) return "";
            return u.PasswordHash;
        }
        #endregion

        #region 是否有哈希密码
        /// <summary>
        /// 是否有哈希密码
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task<bool> HasPasswordAsync(SysUser user)
        {
            var u = await SysUserRepository.FindAsync(user.Id);
            if (u == null) return false;
            return string.IsNullOrWhiteSpace(u.PasswordHash);
        }
        #endregion

        #region 删除登录信息
        /// <summary>
        /// 删除登录信息
        /// </summary>
        /// <param name="user"></param>
        /// <param name="login"></param>
        /// <returns></returns>
        public async Task RemoveLoginAsync(SysUser user, UserLoginInfo login)
        {
            var infos = await SysUserLoginInfoRepository.FindAsync(c => c.UserId == user.Id);
            if (infos == null) return;
            SysUserLoginInfoRepository.SetPhyDelete();//设置物理删除
            await SysUserLoginInfoRepository.DeleteAsync(infos);
        }
        #endregion

        #region 设置邮箱
        /// <summary>
        /// 设置邮箱
        /// </summary>
        /// <param name="user"></param>
        /// <param name="email"></param>
        /// <returns></returns>
        public async Task SetEmailAsync(SysUser user, string email)
        {
            var u = await SysUserRepository.FindAsync(user.Id);
            if (u == null) return;
            u.Email = email;
            await SysUserRepository.UpdateAsync(u);
        }
        #endregion

        #region 设置哈希密码
        /// <summary>
        /// 设置哈希密码
        /// </summary>
        /// <param name="user"></param>
        /// <param name="passwordHash"></param>
        /// <returns></returns>
        public async Task SetPasswordHashAsync(SysUser user, string passwordHash)
        {
            var u = await SysUserRepository.FindAsync(user.Id);
            if (u == null) return;
            u.PasswordHash = passwordHash;
            await SysUserRepository.UpdateAsync(u);
        }
        #endregion

        #region 更新用户
        /// <summary>
        /// 更新用户
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task UpdateAsync(SysUser user)
        {
            var u = await SysUserRepository.FindAsync(user.Id);
            if (u == null) return;
            u = user;
            await SysUserRepository.UpdateAsync(u);
        }
        #endregion

        #region 未实现
        public void Dispose()
        {

        }
        public async Task<int> GetAccessFailedCountAsync(SysUser user)
        {
            return await Task.FromResult(0);
        }
        public Task<bool> GetEmailConfirmedAsync(SysUser user)
        {
            throw new NotSupportedException();
        }
        public async Task<bool> GetTwoFactorEnabledAsync(SysUser user)
        {
            return await Task.FromResult(false);
        }
        public Task<int> IncrementAccessFailedCountAsync(SysUser user)
        {
            throw new NotImplementedException();
        }
        public async Task ResetAccessFailedCountAsync(SysUser user)
        {
            await Task.FromResult(0);
        }
        public Task SetEmailConfirmedAsync(SysUser user, bool confirmed)
        {
            throw new NotSupportedException();
        }
        public async Task SetLockoutEnabledAsync(SysUser user, bool enabled)
        {
            await Task.FromResult(0);
        }
        public async Task SetLockoutEndDateAsync(SysUser user, DateTimeOffset lockoutEnd)
        {
            await Task.FromResult(0);
        }
        public async Task SetTwoFactorEnabledAsync(SysUser user, bool enabled)
        {
            await Task.FromResult(false);
        }
        #endregion
    }
}